package com.tidemark.robot;

import com.google.gdata.client.finance.FinanceService;
import com.google.gdata.client.finance.FinanceUtilities;
import com.google.gdata.data.BaseEntry;
import com.google.gdata.data.BaseFeed;
import com.google.gdata.data.Link;
import com.google.gdata.data.extensions.Money;
import com.google.gdata.data.finance.PortfolioData;
import com.google.gdata.data.finance.PortfolioEntry;
import com.google.gdata.data.finance.PortfolioFeed;
import com.google.gdata.data.finance.PositionData;
import com.google.gdata.data.finance.PositionEntry;
import com.google.gdata.data.finance.PositionFeed;
import com.google.gdata.data.finance.TransactionData;
import com.google.gdata.data.finance.TransactionEntry;
import com.google.gdata.data.finance.TransactionFeed;
import com.google.gdata.util.AuthenticationException;
import com.google.gdata.util.ServiceException;
import com.tidemark.Consts;
import com.tidemark.Stock;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;


public class FinancePortfoliosClient {

	private static final boolean DEBUG = false;

	// Base URL for GData requests
	// GData Server is supplied as command-line argument and
	// appended with /finance/feeds/default
	private static String server = "http://finance.google.com";
	private static String basePath = "/finance/feeds/";
	private static String baseUrl = server + basePath + "default";

	// Feed and Entry URI suffixes:
	private static final String PORTFOLIO_FEED_URL_SUFFIX = "/portfolios";
	private static final String POSITION_FEED_URL_SUFFIX = "/positions";
	private static final String TRANSACTION_FEED_URL_SUFFIX = "/transactions";

	/**
	 * Prints detailed information regarding a Generic Feed
	 * 
	 * @param feed
	 *            The feed of interest
	 */
	private static void printBasicFeedDetails(BaseFeed feed) {
		if (!DEBUG)
			return;

		System.out.println("\tFeed is "
				+ (feed.getCanPost() ? "writable!" : "read-only!"));
		System.out.println("\tNumber of entries: " + feed.getTotalResults());
		System.out.println("\tStart Index: " + feed.getStartIndex());
		System.out.println("\tEnd Index: " + feed.getItemsPerPage());
		System.out.println("\tFeed URI: "
				+ (feed.getSelfLink() == null ? "<none>" : feed.getSelfLink()
						.getHref()) + "\n");
		System.out.println("\tFeed Title: " + feed.getTitle().getPlainText());
		System.out.println("\tAtom ID: " + feed.getId());
		System.out.println("\tLast updated: " + feed.getUpdated());
		System.out.println("\tFeed Categories:");
		Iterator it = feed.getCategories().iterator();
		while (it.hasNext()) {
			System.out.println("\t\t" + it.next().toString());
		}
		System.out.println("\tLinks:");
		if (feed.getLinks().size() == 0) {
			System.out.println("\t\t<No links, sorry!>");
		}
		for (int i = 0; i < feed.getLinks().size(); i++) {
			System.out.println("\t\t" + feed.getLinks().get(i).getHref());
		}
		System.out.println("\t" + "HTML Link: " + feed.getHtmlLink().getHref());
	}

	/**
	 * Prints detailed information regarding a Generic Entry
	 * 
	 * @param entry
	 *            The entry of interest
	 **/
	private static void printBasicEntryDetails(BaseEntry entry) {
		if (!DEBUG)
			return;

		System.out.println("\tTitle: " + entry.getTitle().getPlainText());
		System.out.println("\tAtom ID: " + entry.getId());
		System.out.println("\tLast updated: " + entry.getUpdated());
		System.out.println("\tEntry Categories:");
		Iterator it = entry.getCategories().iterator();
		while (it.hasNext()) {
			System.out.println("\t\t" + it.next().toString());
		}
		System.out.println("\tLinks:");
		if (entry.getLinks().size() == 0) {
			System.out.println("\t\t<No links, sorry!>");
		}
		for (int i = 0; i < entry.getLinks().size(); i++) {
			System.out.println("\t\t"
					+ ((Link) (entry.getLinks().get(i))).getHref());
		}
	}

	/**
	 * Prints detailed contents for a portfolio (i.e. a Portfolio Feed entry)
	 * 
	 * @param portfolioEntry
	 *            The portfolio entry of interest
	 */
	private static void printPortfolioEntry(PortfolioEntry portfolioEntry) {
		if (!DEBUG)
			return;

		System.out.println("\nPortfolio Entry\n---------------");
		printBasicEntryDetails(portfolioEntry);
		System.out.println("\tFeed Link: "
				+ portfolioEntry.getFeedLink().getHref());
		if (portfolioEntry.getFeedLink().getFeed() == null) {
			System.out.println("\tNo inlined feed.");
		} else {
			System.out
					.println("********** Beginning of inline feed ***************");
			printBasicFeedDetails(portfolioEntry.getFeedLink().getFeed());
			PositionFeed inlinedFeed = portfolioEntry.getFeedLink().getFeed();
			printBasicFeedDetails(inlinedFeed);
			for (int i = 0; i < inlinedFeed.getEntries().size(); i++) {
				PositionEntry positionEntry = inlinedFeed.getEntries().get(i);
				printPositionEntry(positionEntry);
			}
			System.out
					.println("************* End of inlined feed *****************");
		}
		PortfolioData portfolioData = portfolioEntry.getPortfolioData();
		System.out.println("\tPortfolio Data:");
		System.out
				.println("\t\tCurrency is " + portfolioData.getCurrencyCode());
		System.out.printf("\t\tPercent Gain is %.2f%%\n", portfolioData
				.getGainPercentage() * 100.0);
		System.out.println("\t\tReturns:");
		System.out.printf("\t\t\tOne week: %.2f%%\n", portfolioData
				.getReturn1w() * 100.0);
		System.out.printf("\t\t\tFour weeks: %.2f%%\n", portfolioData
				.getReturn4w() * 100.0);
		System.out.printf("\t\t\tThree months: %.2f%%\n", portfolioData
				.getReturn3m() * 100.0);
		System.out.printf("\t\t\tYear-to-date: %.2f%%\n", portfolioData
				.getReturnYTD() * 100.0);
		System.out.printf("\t\t\tOne year: %.2f%%\n", portfolioData
				.getReturn1y() * 100.0);
		System.out.printf("\t\t\tThree years: %.2f%%\n", portfolioData
				.getReturn3y() * 100.0);
		System.out.printf("\t\t\tFive years: %.2f%%\n", portfolioData
				.getReturn5y() * 100.0);
		System.out.printf("\t\t\tOverall: %.2f%%\n", portfolioData
				.getReturnOverall() * 100.0);
		if (portfolioData.getCostBasis() == null) {
			System.out.println("\t\tCost Basis not specified");
		} else {
			for (int i = 0; i < portfolioData.getCostBasis().getMoney().size(); i++) {
				Money m = portfolioData.getCostBasis().getMoney().get(i);
				System.out.printf("\t\tThis portfolio cost %.2f %s.\n", m
						.getAmount(), m.getCurrencyCode());
			}
		}
		if (portfolioData.getDaysGain() == null) {
			System.out.println("\t\tDay's Gain not specified");
		} else {
			for (int i = 0; i < portfolioData.getDaysGain().getMoney().size(); i++) {
				Money m = portfolioData.getDaysGain().getMoney().get(i);
				System.out.printf("\t\tThis portfolio made %.2f %s today.\n", m
						.getAmount(), m.getCurrencyCode());
			}
		}
		if (portfolioData.getGain() == null) {
			System.out.println("\t\tTotal Gain not specified");
		} else {
			for (int i = 0; i < portfolioData.getGain().getMoney().size(); i++) {
				Money m = portfolioData.getGain().getMoney().get(i);
				System.out.printf(
						"\t\tThis portfolio has a total gain of %.2f %s.\n", m
								.getAmount(), m.getCurrencyCode());
			}
		}
		if (portfolioData.getMarketValue() == null) {
			System.out.println("\t\tMarket Value not specified");
		} else {
			for (int i = 0; i < portfolioData.getMarketValue().getMoney()
					.size(); i++) {
				Money m = portfolioData.getMarketValue().getMoney().get(i);
				System.out.printf("\t\tThis portfolio is worth %.2f %s.\n", m
						.getAmount(), m.getCurrencyCode());
			}
		}
	}

	/**
	 * Prints detailed contents for a position (i.e. a Position Feed entry)
	 * 
	 * @param positionEntry
	 *            The position entry of interest
	 */
	private static void printPositionEntry(PositionEntry positionEntry) {
		if (!DEBUG)
			return;

		System.out.println("\nPosition Entry\n--------------");
		printBasicEntryDetails(positionEntry);
		System.out.println("\tFeed Link: "
				+ positionEntry.getFeedLink().getHref());
		if (positionEntry.getFeedLink().getFeed() == null) {
			System.out.println("\tNo inlined feed.");
		} else {
			System.out
					.println("********** Beginning of inline feed ***************");
			printBasicFeedDetails(positionEntry.getFeedLink().getFeed());
			TransactionFeed inlinedFeed = positionEntry.getFeedLink().getFeed();
			printBasicFeedDetails(inlinedFeed);
			for (int i = 0; i < inlinedFeed.getEntries().size(); i++) {
				TransactionEntry transactionEntry = inlinedFeed.getEntries()
						.get(i);
				printTransactionEntry(transactionEntry);
			}
			System.out
					.println("************* End of inlined feed *****************");
		}
		System.out.println("\tTicker:");
		System.out.println("\t\tExchange: "
				+ positionEntry.getSymbol().getExchange());
		System.out.println("\t\tSymbol: "
				+ positionEntry.getSymbol().getSymbol());
		System.out.println("\t\tFull Name: "
				+ positionEntry.getSymbol().getFullName());
		PositionData positionData = positionEntry.getPositionData();
		System.out.println("\tPosition Data:");
		System.out.printf("\t\tShare count: %.2f\n", positionData.getShares());
		System.out.printf("\t\tPercent Gain is %.2f%%\n", positionData
				.getGainPercentage() * 100.0);
		System.out.println("\t\tReturns:");
		System.out.printf("\t\t\tOne week: %.2f%%\n", positionData
				.getReturn1w() * 100.0);
		System.out.printf("\t\t\tFour weeks: %.2f%%\n", positionData
				.getReturn4w() * 100.0);
		System.out.printf("\t\t\tThree months: %.2f%%\n", positionData
				.getReturn3m() * 100.0);
		System.out.printf("\t\t\tYear-to-date: %.2f%%\n", positionData
				.getReturnYTD() * 100.0);
		System.out.printf("\t\t\tOne year: %.2f%%\n", positionData
				.getReturn1y() * 100.0);
		System.out.printf("\t\t\tThree years: %.2f%%\n", positionData
				.getReturn3y() * 100.0);
		System.out.printf("\t\t\tFive years: %.2f%%\n", positionData
				.getReturn5y() * 100.0);
		System.out.printf("\t\t\tOverall: %.2f%%\n", positionData
				.getReturnOverall() * 100.0);
		if (positionData.getCostBasis() == null) {
			System.out.println("\t\tCost Basis not specified");
		} else {
			for (int i = 0; i < positionData.getCostBasis().getMoney().size(); i++) {
				Money m = positionData.getCostBasis().getMoney().get(i);
				System.out.printf("\t\tThis position cost %.2f %s.\n", m
						.getAmount(), m.getCurrencyCode());
			}
		}
		if (positionData.getDaysGain() == null) {
			System.out.println("\t\tDay's Gain not specified");
		} else {
			for (int i = 0; i < positionData.getDaysGain().getMoney().size(); i++) {
				Money m = positionData.getDaysGain().getMoney().get(i);
				System.out.printf("\t\tThis position made %.2f %s today.\n", m
						.getAmount(), m.getCurrencyCode());
			}
		}
		if (positionData.getGain() == null) {
			System.out.println("\t\tTotal Gain not specified");
		} else {
			for (int i = 0; i < positionData.getGain().getMoney().size(); i++) {
				Money m = positionData.getGain().getMoney().get(i);
				System.out.printf(
						"\t\tThis position has a total gain of %.2f %s.\n", m
								.getAmount(), m.getCurrencyCode());
			}
		}
		if (positionData.getMarketValue() == null) {
			System.out.println("\t\tMarket Value not specified");
		} else {
			for (int i = 0; i < positionData.getMarketValue().getMoney().size(); i++) {
				Money m = positionData.getMarketValue().getMoney().get(i);
				System.out.printf("\t\tThis position is worth %.2f %s.\n", m
						.getAmount(), m.getCurrencyCode());
			}
		}
	}

	/**
	 * Prints detailed contents for a transaction (i.e. a Transaction Feed
	 * entry)
	 * 
	 * @param transactionEntry
	 *            The transaction entry of interest
	 */
	private static void printTransactionEntry(TransactionEntry transactionEntry) {
		if (!DEBUG)
			return;

		System.out.println("\nTransaction Entry\n-----------------");
		printBasicEntryDetails(transactionEntry);
		TransactionData transactionData = transactionEntry.getTransactionData();
		System.out.println("\tTransaction Data:");
		System.out.println("\t\tType: "
				+ (transactionData.getType() == null ? "no type"
						: transactionData.getType()));
		System.out.println("\t\tDate: "
				+ (transactionData.getDate() == null ? "no date"
						: transactionData.getDate()));
		System.out.printf("\t\tShares: %.2f\n", transactionData.getShares());
		if (transactionData.getPrice() == null) {
			System.out.println("\t\tPrice not specified");
		} else {
			for (int i = 0; i < transactionData.getPrice().getMoney().size(); i++) {
				Money m = transactionData.getPrice().getMoney().get(i);
				System.out.printf(
						"\t\tThis transaction had a unit price of %.2f %s.\n",
						m.getAmount(), m.getCurrencyCode());
			}
		}
		if (transactionData.getCommission() == null) {
			System.out.println("\t\tCommission not specified");
		} else {
			for (int i = 0; i < transactionData.getCommission().getMoney()
					.size(); i++) {
				Money m = transactionData.getCommission().getMoney().get(i);
				System.out.printf(
						"\t\tThis transaction had a commission of %.2f %s.\n",
						m.getAmount(), m.getCurrencyCode());
			}
		}
		System.out.println("\t\tNotes: "
				+ (null == transactionData.getNotes() ? "none"
						: transactionData.getNotes()));
	}

	/**
	 * Queries a portfolio feed and prints feed and entry details.
	 * 
	 * @param service
	 *            authenticated client connection to a Finance GData service
	 * @param feedUrl
	 *            resource URL for the feed, including GData query parameters
	 *            e.g.
	 *            http://finance.google.com/finance/feeds/default/portfolios
	 * @throws IOException
	 *             If there is a problem communicating with the server.
	 * @throws MalformedURLException
	 *             If the URL is invalid.
	 * @throws ServiceException
	 *             If the service is unable to handle the request.
	 */
	private PortfolioFeed queryPortfolioFeed(FinanceService service)
			throws IOException, MalformedURLException, ServiceException {
		String feedUrl = baseUrl + PORTFOLIO_FEED_URL_SUFFIX;

		if (DEBUG)
			System.out.println("Requesting Feed at location: " + feedUrl);
		PortfolioFeed portfolioFeed = service.getFeed(new URL(feedUrl),
				PortfolioFeed.class);
		if (DEBUG)
			System.out.println("\nPortfolio Feed\n==============");
		printBasicFeedDetails(portfolioFeed);
		// for (int i = 0; i < portfolioFeed.getEntries().size(); i++) {
		// PortfolioEntry portfolioEntry = portfolioFeed.getEntries().get(i);
		// printPortfolioEntry(portfolioEntry);
		// }
		return portfolioFeed;
	}

	/**
	 * Inserts a portfolio entry into a feed and prints the new entry.
	 * 
	 * @param service
	 *            authenticated client connection to a Finance GData service
	 * @param feedUrl
	 *            the POST URI associated with the target feed e.g.
	 *            http://finance.google.com/finance/feeds/default/portfolios
	 * @param entry
	 *            the new entry to insert into the feed
	 * @throws IOException
	 *             If there is a problem communicating with the server.
	 * @throws MalformedURLException
	 *             If the URL is invalid.
	 * @throws ServiceException
	 *             If the service is unable to handle the request.
	 */
	private PortfolioEntry insertPortfolioEntry(FinanceService service,
			PortfolioEntry entry) throws IOException, MalformedURLException,
			ServiceException {

		String feedUrl = baseUrl + PORTFOLIO_FEED_URL_SUFFIX;

		if(DEBUG) System.out.println("Inserting Entry at location: " + feedUrl);
		PortfolioEntry insertedEntry = service.insert(new URL(feedUrl), entry);
		printPortfolioEntry(insertedEntry);

		return insertedEntry;
	}

	/**
	 * Queries a position feed and prints feed and entry details.
	 * 
	 * @param service
	 *            authenticated client connection to a Finance GData service
	 * @param feedUrl
	 *            resource URL for the feed, including GData query parameters
	 *            e.g. http://finance.google.com/finance/feeds/default/
	 *            portfolios/1/positions?returns=true
	 * @throws IOException
	 *             If there is a problem communicating with the server.
	 * @throws MalformedURLException
	 *             If the URL is invalid.
	 * @throws ServiceException
	 *             If the service is unable to handle the request.
	 */
	private PositionFeed queryPositionFeed(FinanceService service,
			String portfolioId) throws IOException, MalformedURLException,
			ServiceException {
		String feedUrl = baseUrl + PORTFOLIO_FEED_URL_SUFFIX + "/";
		feedUrl += portfolioId + POSITION_FEED_URL_SUFFIX;

		if (DEBUG)
			System.out.println("Requesting Feed at location " + feedUrl);
		PositionFeed positionFeed = service.getFeed(new URL(feedUrl),
				PositionFeed.class);
		if (DEBUG)
			System.out.println("\nPosition Feed\n=============");
		printBasicFeedDetails(positionFeed);
		// for (int i = 0; i < positionFeed.getEntries().size(); i++) {
		// PositionEntry positionEntry = positionFeed.getEntries().get(i);
		// printPositionEntry(positionEntry);
		// }

		return positionFeed;
	}


	/**
	 * Inserts a transaction entry into a feed and prints the new entry.
	 * 
	 * @param service
	 *            authenticated client connection to a Finance GData service
	 * @param feedUrl
	 *            the POST URI associated with the target feed e.g.
	 *            http://finance.google.com/finance/feeds/default/
	 *            portfolios/1/positions/NYSE:IBM/transactions
	 * @param entry
	 *            the new entry to insert into the feed
	 * @throws IOException
	 *             If there is a problem communicating with the server.
	 * @throws MalformedURLException
	 *             If the URL is invalid.
	 * @throws ServiceException
	 *             If the service is unable to handle the request.
	 */
	private void insertTransactionEntry(FinanceService service, String feedUrl,
			TransactionEntry entry) throws IOException, MalformedURLException,
			ServiceException {
		if(DEBUG) System.out.println("Inserting Entry at location: " + feedUrl);
		TransactionEntry insertedEntry = service
				.insert(new URL(feedUrl), entry);
		printTransactionEntry(insertedEntry);
	}

	private FinanceService service;
	private String portfolioTitle;

	public FinancePortfoliosClient(String portfolioTitle) {
		this.portfolioTitle = portfolioTitle;
		this.service = login();
	}

	/**
	 * open portfolio entry for robot, if not exist, create it.
	 * 
	 * @throws ServiceException
	 * @throws IOException
	 * @throws MalformedURLException
	 */
	private PortfolioEntry openPortfolioEntry() throws MalformedURLException,
			IOException, ServiceException {
		// get portfolio feed,
		PortfolioFeed portfolioFeed = queryPortfolioFeed(service);

		// search for portfolioTitle
		for (int i = 0; i < portfolioFeed.getEntries().size(); i++) {
			PortfolioEntry portfolioEntry = portfolioFeed.getEntries().get(i);
			// printPortfolioEntry(portfolioEntry);
			if (portfolioEntry.getTitle().getPlainText().equals(portfolioTitle)) {
				return portfolioEntry;
			}
		}

		// not found.create new entry
		PortfolioEntry entry = FinanceUtilities.makePortfolioEntry(
				portfolioTitle, "CNY");// CNY is fixed
		PortfolioEntry portfolioEntry = insertPortfolioEntry(service, entry);

		return portfolioEntry;
	}

	public void trade(Stock stock) throws MalformedURLException, IOException,
			ServiceException {

		int suggestion = stock.getSuggestion();

		if (suggestion == Consts.NA) {
			System.out.println("Warning: no suggestion of trading " + stock);
			return;
		}

		// check whether we have the stock or not
		PositionEntry positionEntry = have(stock);

		if (suggestion <= Consts.SALE && positionEntry == null) {
			System.out.println("ignore sell suggestion, we don't have: "
					+ stock);
			return;
		}

		System.out.println("trading: " + stock);
		tradeInternal(stock);

		// else if (suggestion <= Consts.SALE && positionEntry!=null) {
		// tradeInternal(positionEntry, suggestion);
		// return;
		// }
		//
		// else if (suggestion >= Consts.BUY && positionEntry==null) {
		// tradeInternal(positionEntry, suggestion);
		// return;
		// }
		//
		// //if we already have it, add or not? depends...
		// else if (suggestion >= Consts.BUY && positionEntry!=null) {
		// tradeInternal(positionEntry, suggestion);
		// return;
		// }
		//		
		// else{
		// System.out.println("never goes here..");
		// }
	}

	private void tradeInternal(Stock stock)
			throws MalformedURLException, IOException, ServiceException {

		String requestUrl = baseUrl + PORTFOLIO_FEED_URL_SUFFIX + "/";
		
		// System.out.println("Enter portfolio ID");
		String portfolioIdProperty = getSimpleId(openPortfolioEntry().getId());

		// System.out.println("Enter ticker (<exchange>:<ticker>) ");
		String tickerProperty = "";
		if (stock.getCode().startsWith("60")) {
			tickerProperty += "SHA"; // shanghai
		} else if (stock.getCode().startsWith("00")) {
			tickerProperty += "SHE"; // shenzhen
		} else if (stock.getCode().startsWith("30")) {
			tickerProperty += "SHE"; // shenzhen 创业板
		} else {
			throw new MalformedURLException("Unknown code: " + stock.getCode());
		}
		tickerProperty += ":";
		tickerProperty += stock.getCode();

		requestUrl += portfolioIdProperty + POSITION_FEED_URL_SUFFIX + "/"
				+ tickerProperty + TRANSACTION_FEED_URL_SUFFIX;

		int suggestion = stock.getSuggestion();
		// System.out.println("Enter transaction type (Buy, Sell): ");
		String type;
		if (suggestion >= Consts.BUY) {
			type = "Buy";
		} else if (suggestion <= Consts.SALE) {
			type = "Sell";
		} else {
			throw new MalformedURLException("Unknown suggestion: " + suggestion);
		}

		// System.out.println("Enter transaction date (yyyy-mm-dd or blank): ");
		  Date now=new Date();
		  SimpleDateFormat f=new SimpleDateFormat("yyyy-MM-dd");
		  
		String date= f.format(now);

		// System.out.println("Enter number of shares (optional, e.g. 100.0): ");
		String shares = "";
		if (suggestion >= Consts.BUY) {
			shares = "100"; //TODO
		} else if (suggestion <= Consts.SALE) {
			shares = "100"; //TODO
		}

		// System.out.println("Enter price (optional, e.g. 141.14): ");
		String price = "";// TODO

		// System.out.println("Enter commission (optional, e.g. 20.0): ");
		String commission = "";// TODO, no commission

		// System.out.println("Enter currency (optional, e.g. USD, EUR, JPY): ");
		String currency = "CNY";

		// System.out.println("Enter any notes: ");
		String notes = Account.APP_NAME;

		TransactionEntry entry = FinanceUtilities.makeTransactionEntry(type,
				date, shares, price, commission, currency, notes);
		insertTransactionEntry(service, requestUrl, entry);
	}

	private PositionEntry have(Stock stock) throws MalformedURLException,
			IOException, ServiceException {

		// for save, we always check entry before any other operations
		PortfolioEntry portfolioEntry = openPortfolioEntry();

		// search all positions, and compare code
		PositionFeed positionFeed = queryPositionFeed(service,
				getSimpleId(portfolioEntry.getId()));
		for (int i = 0; i < positionFeed.getEntries().size(); i++) {
			PositionEntry positionEntry = positionFeed.getEntries().get(i);
			printPositionEntry(positionEntry);
			if (positionEntry.getSymbol().getSymbol().equals(stock.getCode())) {
				return positionEntry;
			}
		}

		return null;
	}

	private static FinanceService login() {
		FinanceService service = new FinanceService(Account.APP_NAME);
		try {
			service.setUserCredentials(Account.ID, Account.PWD);
		} catch (AuthenticationException e) {
			System.err.println("Invalid Credentials!");
			e.printStackTrace();
		}
		return service;
	}

	private static String getSimpleId(String fullId) {
		int beginIndex = fullId.lastIndexOf('/') + 1;
		int endIndex = fullId.length();
		return fullId.substring(beginIndex, endIndex);
	}
}